#include <assert.h>
#include "events.h"
#include "form_win31.h"

namespace viswidgets
{

viewid_t view_id_root = "form";
const uint form_win31_min_width = 125;
const uint form_win31_min_height = 50;

view_desc_t form_win31_desc = {
	view_id_root,
	wstyle_win31,
	widget_view_handlers,
};

start_event_handling(form_win31_impl)
	handle_resize_event(resize_event_handler)
end_event_handling()

form_win31_impl::form_win31_impl(view_t* vi)
: widget(&form_win31_desc, vi)
, m_client(NULL)
{
	init_caption_format();
	create_client();
}

form_win31_impl::form_win31_impl(const visgrph::canvas& c)
: widget(&form_win31_desc, NULL)
, m_canvas(c), m_client(NULL)
{
	init_caption_format();
	create_client();
}

form_win31_impl::form_win31_impl(int left, int top, int width, int height, view_t* vi)
: widget(left, top, width, height, &form_win31_desc, vi)
, m_client(NULL)
{
	init_caption_format();
	create_client();
}

void form_win31_impl::init_caption_format(void)
{
	m_caption.center();
	m_caption.middle();
	m_caption.wrapping_rect(int(get_title_bar_width(
		getview()->width)), 18);
}

form_win31_impl::~form_win31_impl()
{

}

void form_win31_impl::create_client(void)
{
	assert(NULL == m_client);
	view_t* vi = getview();

	// todo: this is only for normal form
	if (view_rectnull(vi))
		m_client = new form_client(3, 22, -1, -1, vi);
	else
	{
		assert(vi->width >= form_win31_min_width \
			&& vi->height >= form_win31_min_height);
		m_client = new form_client(3, 22,
			vi->width - 3 * 2, vi->height - 3 - 22, vi);
	}
	m_client->setshow(true);
}

void form_win31_impl::on_draw(drawing_context& dc)
{
	view_t* vi = dc.view();
	visgrph::canvas& cvs = dc.canvas();
	visgrph::color linc(0, 0, 0, 255);
	
	cvs.box(0, 0, vi->width, vi->height, linc);

	// fill
	visgrph::color filc(212, 208, 200, 255);
	cvs.rectangle(1, 1, vi->width - 2, 2, filc);
	cvs.rectangle(1, 1, 2, vi->height - 4, filc);
	cvs.rectangle(vi->width - 3, 1, 2, vi->height - 4, filc);
	cvs.rectangle(1, vi->height - 3, vi->width - 2, 2, filc);

	cvs.hline(3, 3, vi->width - 6, linc);
	cvs.vline(3, 3, 19, linc);
	cvs.vline(22, 1, 21, linc);
	cvs.vline(vi->width - 4, 3, 19, linc);
	cvs.vline(vi->width - 23, 1, 21, linc);

	cvs.hline(1, 22, 2, linc);
	cvs.hline(vi->width - 3, 22, 2, linc);
	cvs.hline(1, vi->height - 23, 2, linc);
	cvs.hline(vi->width - 3, vi->height - 23, 2, linc);
	cvs.vline(22, vi->height - 3, 2, linc);
	cvs.vline(vi->width - 23, vi->height - 3, 2, linc);

	draw_ctrl_box(cvs);
	draw_title_bar(cvs, vi);
}

void form_win31_impl::draw_ctrl_box(visgrph::canvas& cvs)
{
	visgrph::color linc(0, 0, 0, 255);			// line color
	visgrph::color refc(255, 255, 255, 255);	// rectangle fill color
	visgrph::color filc(212, 208, 200, 255);	// fill color
	visgrph::color sdwc(128, 128, 128, 255);	// shadow color

	cvs.rectangle(4, 4, 18, 18, filc);
	cvs.box(6, 11, 13, 3, linc);
	cvs.hline(7, 12, 11, refc);
	cvs.hline(7, 14, 13, sdwc);
	cvs.vline(19, 12, 2, sdwc);
}

void form_win31_impl::draw_title_bar(visgrph::canvas& cvs, view_t* vi)
{
	visgrph::color txtc(0, 0, 0, 255);			// text color
	visgrph::color bfilc(165, 203, 247, 255);	// fill color

	uint width = get_title_bar_width(vi->width);
	cvs.rectangle(23, 4, width, 18, bfilc);
	cvs.textout(23, 4, m_caption, txtc);
}

uint form_win31_impl::get_title_bar_width(uint form_width)
{
	// todo:
	return form_width - 23 * 2;
}

void form_win31_impl::resize_event_handler(resize_event& ev)
{
	view_t* vi = getview();
	if (vi->width < form_win31_min_width)
		vi->width = form_win31_min_width;
	if (vi->height < form_win31_min_height)
		vi->height = form_win31_min_height;

	// reset the width of title bar text
	init_caption_format();
	m_client->setpos(3, 22, vi->width - 3 * 2, vi->height - 3 - 22);
}

void form_win31_impl::caption(const char *cap)
{
	m_caption.text(cap);
}

}; // namespace viswidgets
/* EOF */
